{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import statsmodels.api as sm\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "# 设置随机数种子，使运行结果可复现\n",
    "np.random.seed(2046)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>A</th>\n",
       "      <th>B</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>6.075330</td>\n",
       "      <td>d1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>9.420834</td>\n",
       "      <td>d1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.804424</td>\n",
       "      <td>d1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3.921919</td>\n",
       "      <td>d1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>10.804938</td>\n",
       "      <td>d1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>-2.600408</td>\n",
       "      <td>d1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>4.819779</td>\n",
       "      <td>d1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>-0.720696</td>\n",
       "      <td>d1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>5.434779</td>\n",
       "      <td>d1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>1.964238</td>\n",
       "      <td>d1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>8.219257</td>\n",
       "      <td>d2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>-2.701218</td>\n",
       "      <td>d2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>-0.035471</td>\n",
       "      <td>d2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>0.763462</td>\n",
       "      <td>d2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>5.613506</td>\n",
       "      <td>d2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>4.218422</td>\n",
       "      <td>d2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>-3.391276</td>\n",
       "      <td>d2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>3.785496</td>\n",
       "      <td>d2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>0.093028</td>\n",
       "      <td>d2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>-1.105763</td>\n",
       "      <td>d2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            A   B\n",
       "0    6.075330  d1\n",
       "1    9.420834  d1\n",
       "2   -0.804424  d1\n",
       "3    3.921919  d1\n",
       "4   10.804938  d1\n",
       "5   -2.600408  d1\n",
       "6    4.819779  d1\n",
       "7   -0.720696  d1\n",
       "8    5.434779  d1\n",
       "9    1.964238  d1\n",
       "10   8.219257  d2\n",
       "11  -2.701218  d2\n",
       "12  -0.035471  d2\n",
       "13   0.763462  d2\n",
       "14   5.613506  d2\n",
       "15   4.218422  d2\n",
       "16  -3.391276  d2\n",
       "17   3.785496  d2\n",
       "18   0.093028  d2\n",
       "19  -1.105763  d2"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 生成样例数据\n",
    "d1 = np.random.normal(5, 5, 10)\n",
    "d2 = np.random.normal(5, 5, 10)\n",
    "groups = ['d1'] * 10 + ['d2'] * 10\n",
    "d = {'A': np.concatenate((d1, d2)), 'B': groups}\n",
    "data = pd.DataFrame(d)\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           A\n",
      "B           \n",
      "d1  3.831629\n",
      "d2  1.545944\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print(data.groupby('B').mean())\n",
    "data.boxplot('A', by='B', grid=False)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              sum_sq    df         F    PR(>F)\n",
      "B          26.121773   1.0  1.549558  0.229165\n",
      "Residual  303.436158  18.0       NaN       NaN\n"
     ]
    }
   ],
   "source": [
    "# 计算定量特征A与定性特征B之间的eta squared\n",
    "re = sm.OLS.from_formula('A ~ B', data=data).fit()\n",
    "aov_table = sm.stats.anova_lm(re, typ=2)\n",
    "# 打印ANOVA分析结果\n",
    "print(aov_table)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.07926306841913713"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算eta sqaured，根据ANOVA，两者数据并没有显著不同，这与事实相符\n",
    "eta_squared = aov_table['sum_sq'][0] / (aov_table['sum_sq'][0] + aov_table['sum_sq'][1])\n",
    "eta_squared"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
